<?php
namespace classlib\acl;
use \classlib\core\model;
class cookie extends acl_abstract {	
	/**
	 * 构造初始化预设信息
	 * @param array $args
	 */
	public function __construct($args) {
		parent::__construct($args);
	}
	
	/**
	 * 对业务数据进行假面
	 * @param array  $user 加密信息
	 * @param  string $loginpw 加密的字符串
	 * @return string $data
	 */
	public function encrypt($user, $loginpw) {
		$data  = $user['id'].'$'.json_encode($user);
		$hash  = substr(md5($data.$loginpw.$_SERVER['HTTP_USER_AGENT']), 0, 16);
		$data  = bin2hex($data).$hash;
		return $data;
	}
	
	/**
	 * 对数据进行解密
	 * @param  string $user 待加密的资料信息串
	 * @return boolean $res
	 */
	public function decrypt($user) {
		$hash = substr($user, -16);
		$user = substr($user, 0, -16);
		$user = self::hash($user);
		if (!$user || !strpos($user, '$')) {
			return false;
		}
		list($userid, $json) = explode('$', $user, 2);
		//验证解密之后参数的合法性
		if ($userid && $json && is_numeric($userid)) {
			$loginpw  = $this->gs($userid);
			$chkstr = substr(md5($user.$loginpw.$_SERVER['HTTP_USER_AGENT']), 0, 16);
			if (strcmp($hash, $chkstr) == 0) {
				$this->user = json_decode($json, true);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 程序页面验证是否登录
	 * {@inheritDoc}
	 * @see \classlib\acl\acl_abstract::islogin()
	 */
	public function islogin($sign='') {
		if (!$sign && (!isset($_COOKIE[$this->ckey]) || !$_COOKIE[$this->ckey])) {
			return false;
		}
		if ($this->decrypt($sign? $sign:$_COOKIE[$this->ckey])) {
			return true;
		}
		return $this->set_cookie();
	}
		
	/**
	 * 设置一个账号为登录状态
	 * {@inheritDoc}
	 * @see \classlib\acl\acl_abstract::signin()
	 */
	public function signin($user, $loginpw, $expire=0, $cookie=true) {
		$sign = $this->encrypt($user, $loginpw);
		$cookie && $this->set_cookie($sign, $expire);
		return $sign;
	}
	
	/**
	 * 请求cookie以及密钥资料
	 * {@inheritDoc}
	 * @see \classlib\acl\acl_abstract::signout()
	 */
	public function signout($clean=true) {
		if ($this->user) {//清理数据缓存信息
			$orm   = model::load($this->model)->set_mod($this->user['id']);
			$orm->get_orm()->clear()->table($orm->get_table())
				->where('userid', $this->user['id'])->where('sys', $this->sys)->delete();
			$skey = self::skey($this->user['id'], $this->ckey, $this->sys);
			model::$cacher->delete($skey);
		}
		if ($clean) {
			$this->set_cookie();
		}
	}
	
	/**
	 * 清理登录的Cookie资料信息
	 * @param int $expire
	 * @param string $sign
	 * @return boolean
	 */
	private function set_cookie($sign='', $expire=0) {
		if (!$sign) {
			$expire = time() - 3600;
		}
		if (preg_match('/^[\d]{1,3}\./', $_SERVER['SERVER_NAME'])) {
			return setcookie($this->ckey, rawurldecode($sign), $expire, '/');
		} else {
			return setcookie($this->ckey, rawurldecode($sign), $expire, '/', '.'.$_SERVER['SERVER_NAME'], false);
		}
	}
	
	/**
	 * 使用抑或可逆加密逆转
	 * @param string $data
	 * @param string $skey
	 */
	private static function hash($data) {
		$nlen   = strlen($data);
		if ($nlen % 2 != 0) {
			return false;
		}
		$orig   = '';
		for ($i = 0; $i < $nlen;) {
			$orig .= chr(hexdec($data[$i].$data[$i+1]));
			$i    += 2;
		}
		return $orig;
	}
}